<template>
  <a-form-item :label="label" :labelCol="labelCol" :wrapperCol="wrapperCol" :extra="extra">
    <a-tooltip :placement="placement">
      <template slot="title" v-if="tooltip">
        <span>{{tooltip}}</span>
      </template>
      <!--文本框-->
      <a-input v-if="types.includes(type)" :type="type" :placeholder="'请输入'+label" :disabled="disabled" v-decorator="decorator" @change="inputChange" :style="'width:'+width">

        <!--前后置下拉框-->
        <a-select :slot="slotObj.slotName" v-if="slotObj.name&&slotObj.data.length>0" v-decorator="[slotObj.name,{ initialValue: slotObj.value!=''?(slotObj.value):(slotObj.data[0].value) }]" :style="'width:'+slotObj.width+'px'">
          <a-select-option :value="item[valueKey]" v-for="item in slotObj.data">{{item[labelKey]}}</a-select-option>
        </a-select>


        <!--后置图标-->
        <template slot="suffix">
          <slot name="suffix"></slot>
        </template>
        <!--前置图标-->
        <template slot="prefix">
          <slot name="prefix"></slot>
        </template>
        <!--后置组件-->
        <template slot="addonAfter">
          <slot name="addonAfter"></slot>
        </template>
        <!--前置组件-->
        <template slot="addonBefore">
          <slot name="addonBefore"></slot>
        </template>

      </a-input>


      <!--坐标拾取-->
      <a-input v-if="type=='point'" :placeholder="'请选择'+label" :disabled="disabled" v-decorator="decorator" @change="inputChange" :style="'width:'+width">
        <!--后置组件-->
        <template slot="addonAfter">
          <a-icon type="environment" @click="shopMap"/>
          <a-modal :visible="mapVisible" @cancel="mapClose" width="800px" :title="label" @ok="mapClose">
            <a-map :marker="marker" :zoom="zoom" :showSearch="true" :showSearchAreaNum="showSearchAreaNum" @pointClick="pointChange" :clickable="true">
              <template slot-scope="scope" slot="markerIcon">
                <a-icon type="environment" theme="filled" style="font-size: 30px;color: fuchsia"/>
              </template>
            </a-map>
          </a-modal>
        </template>
      </a-input>


      <!--文本域-->
      <a-textarea v-if="type=='textarea'" :placeholder="'请输入'+label" :autosize="true" :disabled="disabled" v-decorator="decorator" @change="inputChange"/>

      <!--数字框-->
      <a-input-number v-if="type=='number'" :min="min" :max="max" v-decorator="decorator" @change="valueChange"/>

      <!--百分比录入框-->
      <a-input-number v-if="type=='percentage'" :min="min" :max="max" :formatter="value => `${value}%`" :parser="value => value.replace('%', '')" v-decorator="decorator" @change="valueChange"/>


      <!--下拉框-->
      <a-select v-if="type=='select'" v-decorator="decorator" :placeholder="'--请选择'+label+'--'" @change="valueChange" :style="'width:'+width" :disabled="disabled">
        <a-select-option :value="item[valueKey]" v-for="item in selectData">{{item[labelKey]}}</a-select-option>
      </a-select>

      <!--复选框-->
      <a-checkbox-group v-if="type=='checkbox'" :name="name" v-decorator="decorator">
        <a-checkbox :value="item[valueKey]" v-for="item in getData">{{item[labelKey]}}</a-checkbox>
      </a-checkbox-group>


      <f-radio v-if="type=='radio'" :data="data" :label-key="labelKey" :value-key="valueKey" :radioButton="radioButton" v-decorator="decorator" @change="inputChange"></f-radio>


      <!--Switch 开关-->
      <a-switch v-if="type=='switch'" :checkedChildren="checkedChildren" :unCheckedChildren="unCheckedChildren" v-decorator="decorator" @change="switchChange"></a-switch>

      <!--日期-->
      <a-date-picker v-if="type=='date'" v-decorator="decorator" :placeholder="'请设置'+label" :style="'width:'+width" @change="dateChange"></a-date-picker>


      <!--上传图片-->
      <upload-images v-if="type=='upload'" v-decorator="decorator" :value-type="valueType" :crop-tip="cropTip" :crop="crop" :crop-size="cropSize" :bus-id="busId" :bus-type="busType" :realRemove="realRemove" :tip="tip" :fileMax="fileMax" @change="uploadSuccess"></upload-images>

      <!--上传视频-->
      <upload-video v-if="type=='video'" v-decorator="decorator" :tip="tip" :fileMax="fileMax" @change="uploadSuccess"></upload-video>

      <!--上传文件-->
      <upload-file v-if="type=='file'" v-decorator="decorator" :accept="accept" :tip="tip" :fileSize="fileSize" :fileMax="fileMax" @change="uploadSuccess"></upload-file>

      <!--城市选择-->
      <area-select v-if="type=='areaSelect'" v-decorator="decorator" :level="level"></area-select>

      <!--自定义标签-->
      <f-tag v-if="type=='tag'" v-decorator="decorator" @change="valueChange"></f-tag>

      <!--富文本-->
      <flyme-editor v-if="type=='editor'" :id="name+'editor'" v-decorator="decorator" @change="editorChange"></flyme-editor>

      <!--级联选择框-->
      <a-cascader v-if="type=='cascader'" v-decorator="decorator" :placeholder="'请选择'+label" :options="selectData" @change="casChange"/>


      <slot></slot>
    </a-tooltip>
  </a-form-item>
</template>
<script>

  import UploadImages from '../UploadImages/UploadImages'
  import UploadVideo from '../UploadVideo/UploadVideo'
  import FlymeEditor from '../Editor/FlymeEditor'
  import { listToTree2 } from '../utils/util'

  export default {
    name: 'fFormItem',
    components: { FlymeEditor, UploadImages, UploadVideo },
    inject: ['formParams'],
    props: {
      /*控件类型*/
      type: {
        type: String,
        default: 'text'
      },
      tooltip: {
        type: String,
        default: ''
      },
      /*控件name,对应实体类属性*/
      name: {
        type: String,
        default: ''
      },
      placement: {
        type: String,
        default: 'topLeft'
      },
      /*FormItem属性*/
      label: {
        type: String,
        default: ''
      },
      lat: {
        type: String,
        default: ''
      },
      lon: {
        type: String,
        default: ''
      },
      marker: {
        type: Array,
        default: function() {
          return []
        }
      },
      zoom: {
        type: Number,
        default: 12
      },
      showSearchAreaNum: {
        type: Number,
        default: 5
      },
      level: {
        type: Number,
        default: 3
      },
      /*提示语*/
      tip: {
        type: String,
        default: ''
      },
      /*控件初始值*/
      value: {
        type: [Number, String, Array, Object, Boolean],
        required: false,
        default: ''
      },
      //取值形式(url,json)
      valueType: {
        type: String,
        default: 'url'
      },
      width: {
        type: [Number, String],
        default: '100%'
      },
      disabled: {
        type: Boolean,
        default: false
      },
      /* 通用数据源 */
      data: {
        type: [String, Array],
        required: false,
        default: null
      },
      /*数据源value对应取值字段*/
      valueKey: {
        type: String,
        default: 'value'
      },
      /*数据源label对应取值字段*/
      labelKey: {
        type: String,
        default: 'label'
      },
      /*是否必填*/
      required: {
        type: Boolean,
        default: false
      },
      /* 验证规则 */
      rules: {
        type: [Boolean, Array, Function],
        required: false,
        default: () => null

      },
      /*自定义验证*/
      validator: {
        type: [Function],
        required: false,
        default: null

      },
      /*数据类型,验证时使用,当数据为数字时dataType=number否则验证失效*/
      dataType: {
        type: String,
        default: 'string'
      },
      /*验证规则:最小字符数*/
      min: {
        type: Number,
        default: 0
      },
      /*验证规则:最大字符数*/
      max: {
        type: Number,
        default: 999999999
      },
      /*参考FormItem属性 */
      extra: {
        type: String,
        default: ''
      },
      /*最大上传文件数量*/
      fileMax: {
        type: Number,
        default: 1
      },
      fileSize: {
        default: 204800
      },
      accept: {
        type: [String],
        default: '.*'
      },
      /*radio控件样式*/
      radioButton: {
        type: Boolean,
        default: false
      },
      //文件业务ID
      busId: {
        type: String,
        default: ''
      },
      //文件所属业务类型
      busType: {
        type: String,
        default: ''
      },
      //文件真实删除
      realRemove: {
        type: Boolean,
        default: false
      },
      checkedChildren: {
        type: String,
        default: '开'
      },
      unCheckedChildren: {
        type: String,
        default: '关'
      },
      //是否开启裁剪上传
      crop: {
        type: Boolean,
        default: false
      },
      //裁剪框大小
      cropSize: {
        type: [String, Array],
        default: 'small'
      },
      cropTip: {
        type: String,
        default: ''
      },
      slotObj: {
        type: [Object],
        required: false,
        default: () => {
          return {
            name: '',
            slotName: '',
            value: '',
            width: 100,
            data: []
          }
        }
      }
    },
    data() {
      return {
        selectData: [],
        mapVisible: false,
        switchValue: 1,
        showTag: false,
        types: ['text', 'password'],
        labelCol: {
          xs: { span: 24 },
          sm: { span: 3 }
        },
        wrapperCol: {
          xs: { span: 24 },
          sm: { span: 20 }
        }
      }
    },
    methods: {
      inputChange(e) {
        this.$emit('update:value', e.target.value)
        this.$emit('change', e.target.value)
      },
      pointChange(position) {
        this.$emit('update:lat', String(position.lat))
        this.$emit('update:lon', String(position.lng))
        this.$emit('change', position)
      },
      valueChange(value) {
        console.log('changed', value)
        this.$emit('update:value', value)
      },
      switchChange(value) {
        console.log('changed', Number(value))
        this.$emit('update:value', Number(value))
      },
      shopMap() {
        this.mapVisible = true
      },
      mapClose() {
        this.mapVisible = false
      },
      dateChange(date, dateStr) {
        this.$emit('update:value', dateStr)
        this.$emit('change', dateStr, date)
        this.formParams[this.name] = dateStr
      },
      uploadSuccess(fileUrl, files, fileIds, removeIds) {
        console.info('上传回调:fileUrl', fileUrl)
        console.info('上传回调:files', files)
        console.info('上传回调:fileIds', fileIds)
        console.info('上传回调:removeIds', removeIds)
        if (fileUrl) {
          this.$emit('uploadSuccess', fileUrl, files, fileIds, removeIds)
        }
      },
      casChange(value, opt) {
        this.$emit('change', value, opt)
      },
      editorChange(html) {
        this.$emit('update:value', html)
        this.$emit('change', html)
      }
    },
    computed: {
      decorator: function() {
        let obj = [this.name]
        let hasVaild = false
        let config = {}
        let rule = []
        let message = this.label + '不能为空!'
        if (typeof this.rules == 'object' && this.rules != null) {
          this.rules[0].required = this.required
          this.rules[0].message = message
          if (this.validator && this.validator != null) {
            this.rules.push({ validator: this.validator })
          }
          rule = this.rules
          hasVaild = true
        } else {
          if (this.required) {
            rule = [{ required: true, message: message, trigger: 'change', type: this.dataType }]
            hasVaild = true
          }
        }
        //添加验证规则
        if (hasVaild) {
          config.rules = rule
        }
        if (this.type != 'date') {
          config.initialValue = this.value
        } else {
          config.initialValue = this.$moment(this.value ? this.value : new Date(), 'YYYY-MM-DD')
        }
        if (this.required && this.dataType == 'string') {
          if (['number', 'percentage', 'radio', 'select'].includes(this.type)) {

            if (this.value && typeof this.value == 'number') {
              config.rules[0].type = 'number'
            } else {
              config.rules[0].type = 'string'
            }
          }
          if (this.type == 'areaSelect') {
            config.rules[0].type = 'array'
          }
          if (this.type == 'date') {
            config.rules[0].type = 'object'
          }

        }
        if (this.type == 'switch') {
          config.valuePropName = 'checked'
          config.initialValue = Boolean(this.value)
        }
        obj.push(config)
        return obj
      },
      getSwitch: {
        get() {
          return this.value == this.switchValue
        },
        set(val) {
          this.switchValue = val
        }

      },
      getData: function() {
        if (this.data) {
          if (typeof this.data == 'object' || typeof this.data == 'Array') {
            return this.data
          }
        }
      }
    },
    mounted() {
      this.showTag = true
    },
    created() {
      if (this.data) {
        if (typeof this.data == 'object' || typeof this.data == 'Array') {
          this.selectData = this.data
        }
        if (typeof this.data == 'string') {
          this.http.get(this, {
            url: this.data,
            success: function(me, data) {
              if (me.type == 'cascader') {
                me.selectData = listToTree2(data, {
                  primaryKey: 'categoryId',
                  titleKey: 'categoryName'
                })
              } else {
                me.selectData = data
              }
            }
          })
        }
      }

    }
  }
</script>
<style>
  .ant-cascader-menu {

  }

</style>
